package com.siyoumi.app.netty;

import com.siyoumi.app.entity.IotDevice;
import com.siyoumi.app.modules.iot.service.SvcIotDevice;
import com.siyoumi.app.netty.entity.NettyMsg;
import com.siyoumi.app.netty.entity.NettyRoomUser;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.mqtt.MqttConnectMessage;
import io.netty.handler.codec.mqtt.MqttFixedHeader;
import io.netty.handler.codec.mqtt.MqttMessageType;
import lombok.extern.slf4j.Slf4j;

//服务端-验证处理
@Slf4j
public class NettyMqttAuthHandler
        extends SimpleChannelInboundHandler<MqttConnectMessage> {
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.debug("{}----exceptionCaught:{}", ctx.channel().id().asShortText(), cause.getMessage());
        super.exceptionCaught(ctx, cause);

        Channel channel = ctx.channel();
        if (channel.isActive()) {
            channel.close();
        }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MqttConnectMessage msg) throws Exception {
        log.debug("id:{}", ctx.channel().id());

        String clientId = msg.payload().clientIdentifier();
        String pwd = XStr.toString(msg.payload().passwordInBytes());
        log.info("userName: {}", msg.payload().userName());
        log.info("pwd: {}", pwd);
        log.info("clientId: {}", clientId);

        MqttFixedHeader mqttFixedHeader = msg.fixedHeader();
        if (mqttFixedHeader.messageType().equals(MqttMessageType.CONNECT)) {
            //	在一个网络连接上，客户端只能发送一次CONNECT报文。服务端必须将客户端发送的第二个CONNECT报文当作协议违规处理并断开客户端的连接
            //	建议connect消息单独处理，用来对客户端进行认证管理等 这里直接返回一个CONNACK消息
            NettyMqttUtil.connack(ctx, msg);
        }

        String[] idArr = clientId.split("\\.");
        if (idArr.length != 2) {
            log.debug("设备username异常");
            NettyUtil.sendTextAndClose(ctx.channel(), NettyMsg.getR("", 5040, "设备username异常"));
            return;
        }
        IotDevice entityDev = SvcIotDevice.getBean().getEntity(idArr[0], idArr[1]);
        if (entityDev == null) {
            log.debug("设备ID异常");
            NettyUtil.sendTextAndClose(ctx.channel(), NettyMsg.getR("", 50050, "设备ID异常"));
            return;
        }

        XReturn rCheckPwd = SvcIotDevice.getBean().checkPwd(entityDev, pwd);
        if (rCheckPwd.err()) {
            log.debug("设备签名失败, {}", XStr.toJsonStr(rCheckPwd));
            XValidator.err(NettyMsg.getR("", rCheckPwd.getErrCode(), rCheckPwd.getErrMsg()));
            //NettyUtil.sendTextAndClose(ctx.channel(), NettyMsg.getR("", rCheckPwd.getErrCode(), rCheckPwd.getErrMsg()));
            return;
        }

        log.debug("{}--验证成功：删除管道", ctx.channel().id());
        ctx.pipeline().remove(this);

        String mqttQueueId = SvcIotDevice.getBean().getMqttQueueId(entityDev);
        XReturn r = XReturn.getR(0);
        r.setData("x", entityDev.getIdev_x_id());
        r.setData("openid", mqttQueueId);
        NettyUtil.setTokenData(ctx.channel(), r);

        NettyMqttUtil.getMapChannel().put(SvcIotDevice.getBean().getMqttQueueId(entityDev), ctx.channel());

        ctx.pipeline().remove(this);
        //执行下一个管道ChannelActive
        ctx.fireChannelActive();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.debug("auth连接");
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.debug("auth断开");
        super.channelInactive(ctx);
    }
}
